var Tools = {
  /**
   * 创建图片对象
   * @param {string} src
   * @param {number} w
   * @param {number} h
   * @returns {Image}
   */
  createImg: function (src, w, h) {
    let img = new Image();
    img.src = src;
    if (w) img.width = w;
    if (h) img.height = h;
    return img;
  },

  /**
   * 给定起始和终点坐标,获取路径所有坐标
   * @param {number} x0 起始坐标x
   * @param {number} y0 起始坐标y
   * @param {number} x1 终点坐标x
   * @param {number} y1 终点坐标y
   * @param {space} space 坐标间隙
   * @param {number} outLen 当ext为true时,超出屏幕边缘的阈值
   * @param {boolean} ext 是否沿伸到屏幕边缘
   * @returns {Point[]} 坐标集
   */
  calcLinePoints(x0, y0, x1, y1, space = 2, outLen = 0, ext = false) {
    //坐标集合
    let points = [];
    let dx = x1 - x0; //计算底边
    let dy = y1 - y0; //计算高
    //获取最长边
    let max_step = Math.round(Math.max(Math.abs(dx), Math.abs(dy)));
    //获取第一个坐标,并以此当做它们的步长
    let x_step = parseFloat(dx / max_step);
    let y_step = parseFloat(dy / max_step);
    //当前坐标
    let x = x0;
    let y = y0;
    if (!ext) {
      //循环直到目标点
      for (let i = 0; i <= max_step; i += space) {
        x = i * x_step + x0;
        y = i * y_step + y0;
        points.push(new Point(x, y));
      }
    } else {
      let width = gameCanvas.width + outLen;
      let height = gameCanvas.height + outLen;
      //循环直达边缘
      for (let i = 0; x >= -outLen && x <= width && y >= -outLen && y <= height; i += space) {
        x = i * x_step + x0;
        y = i * y_step + y0;
        points.push(new Point(x, y));
      }
    }

    return points;
  },
  /**
   * 给定起始和终点坐标,计算角度
   * @param {number} x0 起始坐标x
   * @param {number} y0 起始坐标y
   * @param {number} x1 终点坐标x
   * @param {number} y1 终点坐标y
   */
  calcAngle(x0, y0, x1, y1) {
    let atan = Math.atan2(y1 - y0, x1 - x0);
    return (atan * 180) / Math.PI + 90;
  },

  /**
   * 计算一点绕圆心旋转之后的坐标
   * @param {Point} o 圆心坐标
   * @param {Point} a 起始点坐标
   * @param {number} angle 旋转角度
   */
  calcRolCoor(o, a, angle) {
    let b = new Point();
    angle = (angle * Math.PI) / 180;
    b.x = (a.x - o.x) * Math.cos(angle) - (a.y - o.y) * Math.sin(angle) + o.x;
    b.y = (a.x - o.x) * Math.sin(angle) + (a.y - o.y) * Math.cos(angle) + o.y;
    return b;
  },

  /**
   * @desc 二阶贝塞尔,返回曲线单点坐标
   * @param {number} t 当前百分比
   * @param {Point} p1 起点坐标
   * @param {Point} p2 终点坐标
   * @param {Point} cp 控制点
   * @returns {Point} 曲线点坐标
   */
  twoBezier(t, p1, p2, cp) {
    let x1 = p1.x,
      y1 = p1.y,
      cx = cp.x,
      cy = cp.y,
      x2 = p2.x,
      y2 = p2.y;
    let x = (1 - t) * (1 - t) * x1 + 2 * t * (1 - t) * cx + t * t * x2;
    let y = (1 - t) * (1 - t) * y1 + 2 * t * (1 - t) * cy + t * t * y2;
    return new Point(x, y);
  },

  /**
   * @desc 三阶贝塞尔,返回曲线单点坐标
   * @param {number} t 当前百分比
   * @param {Point} p1 起点坐标
   * @param {Point} p2 终点坐标
   * @param {Point} cp1 控制点1
   * @param {Point} cp2 控制点2
   * @returns {Point} 曲线点坐标
   */
  threeBezier(t, p1, cp1, cp2, p2) {
    let x1 = p1.x,
      y1 = p1.y,
      x2 = p2.x,
      y2 = p2.y,
      cx1 = cp1.x,
      cy1 = cp1.y,
      cx2 = cp2.x,
      cy2 = cp2.y;
    let x = x1 * (1 - t) * (1 - t) * (1 - t) + 3 * cx1 * t * (1 - t) * (1 - t) + 3 * cx2 * t * t * (1 - t) + x2 * t * t * t;
    let y = y1 * (1 - t) * (1 - t) * (1 - t) + 3 * cy1 * t * (1 - t) * (1 - t) + 3 * cy2 * t * t * (1 - t) + y2 * t * t * t;
    return new Point(x, y);
  },

  /**
   * 返回二次贝塞尔曲线坐标集
   * @param {Point} start 起始坐标
   * @param {Point} end 结束坐标
   * @param {Point} c1 控制点1
   * @param {number} space 百分比步长,可以是小数
   * @returns {Point[]} 坐标集
   */
  calcTwoBezierPoints(start, end, c1, space = 0.5) {
    var points = [];
    for (let i = 1; i <= 100; i += space) {
      points.push(this.twoBezier(i / 100, start, end, c1));
    }
    return points;
  },

  /**
   * 返回三次贝塞尔曲线坐标集
   * @param {Point} start 起始坐标
   * @param {Point} end 结束坐标
   * @param {Point} c1 控制点1
   * @param {Point} c2 控制点2
   * @param {number} space 百分比步长,可以是小数
   * @returns {Point[]} 坐标集
   */
  calcThreeBezierPoints(start, end, c1, c2, space = 0.8) {
    var points = [];
    for (let i = 1; i <= 100; i += space) {
      points.push(this.threeBezier(i / 100, start, c1, c2, end));
    }
    return points;
  },
  /**生成范围内随机整数(包含边界) */
  getRandInt(start, end) {
    if (start == end) return start;
    return start + Math.floor(Math.random() * (end - start));
  },
};
